﻿using CoreApi.Meta;
using System.Collections.Generic;
using System.Linq;

namespace CoreApi.Impl
{
    public class Thresholder:IThresholder
    {
        internal class bpData
        {
            public int AgeMin { get; set; }
            public int AgeMax { get; set; }
            public string Gender { get; set; }
            public int Sbp { get; set; }
            public int Dbp { get; set; }
        }
        internal class bpKey
        {
            public string Phase { get; set; }
            public int[] Sbp { get; set; }
            public int[] Dbp { get; set; }
        }
        internal class glData
        {
            public string Meal { get; set; }
            public float Value { get; set; }
        }
        
        internal class glKey
        {
            public string Phase {get;set;}
            public string Meal { get; set; }
            public float Value { get; set; }
        }

        private bpData[] BPStandard = new bpData[]{
            new bpData(){AgeMin=0,AgeMax=15, Gender=Gender.Male, Sbp=110,Dbp=72}
            ,new bpData(){ AgeMin=16, AgeMax=20, Gender=Gender.Male, Sbp=115, Dbp=73}
            ,new bpData(){ AgeMin=21, AgeMax=25, Gender=Gender.Male, Sbp=115, Dbp=73}
            ,new bpData(){ AgeMin=26, AgeMax=30, Gender=Gender.Male, Sbp=115, Dbp=75}
            ,new bpData(){ AgeMin=31, AgeMax=35, Gender=Gender.Male, Sbp=117, Dbp=76}
            ,new bpData(){ AgeMin=36, AgeMax=40, Gender=Gender.Male, Sbp=120, Dbp=80}
            ,new bpData(){ AgeMin=41, AgeMax=45, Gender=Gender.Male, Sbp=124, Dbp=81}
            ,new bpData(){ AgeMin=46, AgeMax=50, Gender=Gender.Male, Sbp=128, Dbp=82}
            ,new bpData(){ AgeMin=51, AgeMax=55, Gender=Gender.Male, Sbp=134, Dbp=84}
            ,new bpData(){ AgeMin=56, AgeMax=60, Gender=Gender.Male, Sbp=137, Dbp=84}
            ,new bpData(){ AgeMin=61, AgeMax=65, Gender=Gender.Male, Sbp=148, Dbp=86}
            ,new bpData(){ AgeMin=66, AgeMax=150, Gender=Gender.Male, Sbp=148, Dbp=90}
            ,new bpData(){AgeMin=0,AgeMax=15, Gender=Gender.Female, Sbp=100,Dbp=70}
            ,new bpData(){ AgeMin=16, AgeMax=20, Gender=Gender.Female, Sbp=110, Dbp=70}
            ,new bpData(){ AgeMin=21, AgeMax=25, Gender=Gender.Female, Sbp=110, Dbp=71}
            ,new bpData(){ AgeMin=26, AgeMax=30, Gender=Gender.Female, Sbp=112, Dbp=73}
            ,new bpData(){ AgeMin=31, AgeMax=35, Gender=Gender.Female, Sbp=114, Dbp=74}
            ,new bpData(){ AgeMin=36, AgeMax=40, Gender=Gender.Female, Sbp=116, Dbp=77}
            ,new bpData(){ AgeMin=41, AgeMax=45, Gender=Gender.Female, Sbp=122, Dbp=78}
            ,new bpData(){ AgeMin=46, AgeMax=50, Gender=Gender.Female, Sbp=128, Dbp=79}
            ,new bpData(){ AgeMin=51, AgeMax=55, Gender=Gender.Female, Sbp=134, Dbp=80}
            ,new bpData(){ AgeMin=56, AgeMax=60, Gender=Gender.Female, Sbp=139, Dbp=82}
            ,new bpData(){ AgeMin=61, AgeMax=65, Gender=Gender.Female, Sbp=145, Dbp=83}
            ,new bpData(){ AgeMin=66, AgeMax=150, Gender=Gender.Female, Sbp=145, Dbp=85}
        };

        private bpKey[] HighBPKeys = new bpKey[]{
            new bpKey(){ Phase="高血压二阶段(160/100)", Sbp=new int[]{160,999},Dbp=new int[]{100,999}}
            ,new bpKey(){ Phase="高血压一阶段(140-159/90-99)", Sbp=new int[]{140,159},Dbp=new int[]{90,99}}    
            ,new bpKey(){ Phase="早期(120-139/80-89)", Sbp=new int[]{120,139}, Dbp=new int[]{80,89}}
        };

        private bpKey[] LowBPKeys = new bpKey[]{
            new bpKey(){ Phase="低血压(90/60)", Sbp=new int[]{ 0,90}, Dbp=new int[]{0,60} }
            ,new bpKey() { Phase="低血压(100/70)", Sbp=new int[]{0,100}, Dbp=new int[]{0,70} }
        };

        private glData[] GLStandard = new glData[]{
            new glData(){ Meal=MealType.BeforeMeal, Value=6.11f }
            ,new glData(){ Meal=MealType.AfterMeal, Value=7.8f }
            ,new glData(){ Meal=MealType.Unknown, Value=7.8f }
        };

        private glKey[] HighGLKeys = new glKey[]{
            new glKey(){ Phase="糖尿病(空腹 >=7.0)", Meal=MealType.BeforeMeal, Value=7.0f }
            ,new glKey(){ Phase="糖尿病(任何时候 >=11.1)", Meal=MealType.Unknown, Value=11.1f}
            ,new glKey(){ Phase="糖尿病(饭后 >=11.1)", Meal=MealType.AfterMeal, Value=11.1f}
        };

        private glKey[] LowGLKeys = new glKey[]{
            new glKey(){ Phase="低血糖(空腹 <2.8)", Meal=MealType.BeforeMeal, Value=2.8f }
            ,new glKey(){ Phase="低血糖(空腹 <2.8)", Meal=MealType.Unknown, Value=2.8f }
        };

        public ReturnValue BPIsHealth(string gender, int age, int sbp, int dbp)
        {
            if (age < 50 && LowBPKeys[0].Sbp[1] > sbp && LowBPKeys[0].Dbp[1] > dbp) return new ReturnValue(false, LowBPKeys[0].Phase);
            if (age >= 50 && LowBPKeys[1].Sbp[1] > sbp && LowBPKeys[1].Dbp[1] > dbp) return new ReturnValue(false, LowBPKeys[1].Phase);
            bpData d = BPStandard.FirstOrDefault<bpData>(x => (x.Gender.Equals(gender) && x.AgeMin <= age && x.AgeMax >= age));
            if (d != null && (d.Sbp < sbp || d.Dbp < dbp))
            {
                foreach (bpKey k in HighBPKeys)  if (k.Sbp[0] <= sbp) return new ReturnValue(false, k.Phase);
                return new ReturnValue(false, string.Format("参考({0}/{1})", d.Sbp, d.Dbp));
            }
            else if (d!=null) return new ReturnValue();
            else foreach(bpKey k in HighBPKeys) if (k.Sbp[0]<=sbp && k.Dbp[0]<=dbp) return new ReturnValue(false,k.Phase);
            return new ReturnValue();
        }

        public ReturnValue GlycemicIsHealth(string meal, float value)
        {
            foreach (glKey k in LowGLKeys) if (k.Value > value) return new ReturnValue(false, k.Phase);
            glData gd = GLStandard.FirstOrDefault<glData>(x => x.Meal.Equals(meal));
            if (gd != null && gd.Value > value) return new ReturnValue();
            else if (gd != null)
            {
                foreach (glKey k in HighGLKeys) if (meal.Equals(k.Meal) && value >= k.Value) return new ReturnValue(false, k.Phase);
                return new ReturnValue(false, string.Format("参考值({0})", gd.Value));
            }
            return new ReturnValue();
        }
    }
}
